#include "driver/gpio.h"
#include "driver/ledc.h"
#include "esp_log.h"
#include "atomizer.h"

#define TAG "ATOMIZER"

atomizer_t atomizer1;

/**
 * @brief 初始化雾化器
 * @param atomizer 雾化器配置结构体
 * @return ESP_OK成功，其他值失败
 */
esp_err_t atomizer_init(atomizer_t *atomizer)
{
    esp_err_t err;

    // 配置LEDC定时器用于PWM输出
    ledc_timer_config_t ledc_timer = {
        .speed_mode      = LEDC_LOW_SPEED_MODE,
        .timer_num       = atomizer->ledc_timer,
        .duty_resolution = LEDC_TIMER_4_BIT, // 4位分辨率，0-15
        .freq_hz         = atomizer->freq,   // 雾化器工作频率
        .clk_cfg         = LEDC_AUTO_CLK};
    err = ledc_timer_config(&ledc_timer);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "failed to config ledc timer");
        return err;
    }

    // 配置LEDC通道用于GPIO输出
    ledc_channel_config_t ledc_channel = {
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .channel    = atomizer->ledc_channel,
        .timer_sel  = atomizer->ledc_timer,
        .intr_type  = LEDC_INTR_DISABLE,
        .gpio_num   = atomizer->atomizer_gpio,
        .duty       = 0, // 初始占空比为0%
        .hpoint     = 0};
    err = ledc_channel_config(&ledc_channel);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "failed to config ledc channel");
        return err;
    }
    
    atomizer->enable_flag = false;

    //  // 配置使能开关GPIO输出
    //  gpio_config_t gpio_conf = {
    //      .pin_bit_mask = (1 << atomizer->atomizer_gpio),
    //      .mode         = GPIO_MODE_OUTPUT,
    //      .pull_up_en   = GPIO_PULLUP_DISABLE,
    //      .pull_down_en = GPIO_PULLDOWN_DISABLE,
    //      .intr_type    = GPIO_INTR_DISABLE,
    //  };

    //  gpio_config(&gpio_conf);

    return ESP_OK;
}

/**
 * @brief 开启雾化器
 * @param atomizer 雾化器配置结构体
 * @return ESP_OK成功，其他值失败
 */
esp_err_t atomizer_on(atomizer_t *atomizer)
{
    esp_err_t err;
    // 设置50%占空比 (256/512)
    err = ledc_set_duty(LEDC_LOW_SPEED_MODE, atomizer->ledc_channel, atomizer->duty_rate * ATOMIZER1_LEDC_FREQ_HZ);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "failed to set duty");
        return err;
    }

    err = ledc_update_duty(LEDC_LOW_SPEED_MODE, atomizer->ledc_channel);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "failed to update duty");
        return err;
    }

    atomizer->enable_flag = true;

    return ESP_OK;
}

/**
 * @brief 关闭雾化器
 * @param atomizer 雾化器配置结构体
 * @return ESP_OK成功，其他值失败
 */
esp_err_t atomizer_off(atomizer_t *atomizer)
{
    esp_err_t err;
    // 设置0%占空比
    err = ledc_set_duty(LEDC_LOW_SPEED_MODE, atomizer->ledc_channel, 0);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "failed to set duty");
        return err;
    }

    err = ledc_update_duty(LEDC_LOW_SPEED_MODE, atomizer->ledc_channel);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "failed to update duty");
        return err;
    }
    
    atomizer->enable_flag = false;

    return ESP_OK;
}

/**
 * @brief 设置雾化器占空比
 * @param atomizer 雾化器配置结构体
 * @param duty_rate 占空比
 * @return ESP_OK成功，其他值失败
 */
esp_err_t atomizer_duty_rate_set(atomizer_t *atomizer, float duty_rate)
{
    if (duty_rate < 0)
        duty_rate = 0;
    else if (duty_rate > 1)
        duty_rate = 1;

    atomizer->duty_rate = duty_rate;

    return ESP_OK;
}
